home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Games
/
NeXTmj
/
Source
/
GameCoordinator.cc
< prev
next >
Wrap
Text File
|
1991-03-23
|
7KB
|
350 lines
/*
*
$Author$
$Header$
*
$Log$
*/
#import "GameCoordinator.h"
#import "Tile.h"
#import "TileIterator.h"
extern "C" {
#import <assert.h>
#import <string.h>
}
GameCoordinator::GameCoordinator( GameBoardView* view, TileCountManager* manager ) {
int board_num = -1;
initialized = NO;
assert( view );
my_view = view;
assert( manager );
tile_count_manager = manager;
// Scan the command line and look
// for an optional board number. The
// board number is a seed to the random
// number generator.
for( int i = 0; i < NXArgc; ++i )
if( !strncmp( NXArgv[ i ], "-b", strlen( "-b" )))
if(( i + 1 ) < NXArgc ) {
board_num = atoi( NXArgv[ i + 1 ] );
board_num %= 20011;
}
// Scramble the tiles on the game
// board.
if( board_num == -1 )
scrambler.scramble( tile_array );
else
scrambler.scramble( board_num, tile_array );
// Prepare the tiles for
// a the game.
prepareTilesForPlay();
// All tiles are unselected in their
// constructor but this method does
// some additional work.
unselectTiles();
// All tiles are placed on the board.
tile_count_manager->resetCount();
// Insure the view is dirty so that
// it'll be displayed when the window
// is exposed.
updateView();
initialized = YES;
}
void GameCoordinator::updateView( void ) {
[ my_view setNeedsDisplay:YES ];
if( initialized )
[ my_view display ];
}
void GameCoordinator::drawImage( void ) {
assert([ my_view isFocusView ]);
// Have each tile that is marked as
// not removed to draw itself on the
// Game Board.
for( int i = 0; i < tile_array.size(); ++i )
if( !tile_array[ i ].isRemoved())
tile_array[ i ].drawImage( description_array[ i ]->tileLocation());
}
void GameCoordinator::helpClick( void ) {
unselectTiles();
help.helpClick( tile_array );
updateView();
}
void GameCoordinator::undoClick( void ) {
assert(( undoList.count() % 2 ) == 0 );
help.resetHelp();
// If there are two tiles on the undo
// list then mark them as not removed,
// redraw the board, and mark all
// tiles as not selected.
if( undoList.count()) {
for( int i = 0; i < 2; ++i ) {
int tile = undoList.lastValue();
tile_array[ tile ].setRemoved( NO );
undoList -= tile;
}
updateSelectablilty();
tile_count_manager->addTwo();
} else
NXBeep();
unselectTiles();
updateView();
}
void GameCoordinator::unselectTiles( void ) {
for( int i = 0; i < tile_array.size(); ++i )
tile_array[ i ].setSelected( NO );
first_selected_tile =
second_selected_tile = -1;
updateView();
}
void GameCoordinator::againClick( void ) {
// Again means to play the same tile
// scramble again.
help.resetHelp();
prepareTilesForPlay();
undoList.empty();
unselectTiles();
updateView();
tile_count_manager->resetCount();
}
void GameCoordinator::newClick( void ) {
// Scramble the tiles and start
// a new game.
scrambler.scramble( tile_array );
undoList.empty();
help.resetHelp();
unselectTiles();
prepareTilesForPlay();
updateView();
tile_count_manager->resetCount();
}
void GameCoordinator::prepareTilesForPlay( void ) {
int i;
// Set all tiles to a default
// state.
for( i = 0; i < tile_array.size(); ++i ) {
tile_array[ i ].setRemoved( NO );
tile_array[ i ].setSelected( NO );
tile_array[ i ].setSelectable( NO );
}
updateSelectablilty();
}
void GameCoordinator::updateSelectablilty( void ) {
// Any tile that is free on either its
// left or right and isn't covered
// is selectable
for( int i = 0; i < tile_array.size(); ++i ) {
BOOL selectable = NO;
if( !tile_array[ i ].isRemoved())
if( !isCovered( i ))
if( isRightFree( i ) || isLeftFree( i ))
selectable = YES;
tile_array[ i ].setSelectable( selectable );
}
}
BOOL GameCoordinator::isFree( IntegerList& list ) {
BOOL is_free = YES;
int i;
list.beginIterate();
while(( i = list()) != -1 )
if( !tile_array[ i ].isRemoved())
is_free = NO;
return is_free;
}
void GameCoordinator::click( const NXPoint* aPoint ) {
int theTile = tileForClick( aPoint );
// Any click on the Game Board resets
// Help.
if( help.isSelected())
unselectTiles();
help.resetHelp();
if( theTile != -1 ) {
if( tile_array[ theTile ].isSelectable()) {
// If the tile is being unselected
// the unselect it.
if( theTile == first_selected_tile ) {
tile_array[ first_selected_tile ].setSelected( NO );
first_selected_tile = -1;
} else
if( theTile == second_selected_tile ) {
tile_array[ second_selected_tile ].setSelected( NO );
second_selected_tile = -1;
} else
// If tile isn't selected then
// this tile is selected.
if( first_selected_tile == -1 ) {
tile_array[ theTile ].setSelected( YES );
first_selected_tile = theTile;
} else
if( second_selected_tile == -1 ) {
tile_array[ theTile ].setSelected( YES );
second_selected_tile = theTile;
}
// If there are two tiles selected
// then compare their types. If they're
// different then unselect the tiles.
if(( first_selected_tile != -1 ) && ( second_selected_tile != -1 ))
if( tile_array[ first_selected_tile ].tileType() != tile_array[ second_selected_tile ].tileType()) {
unselectTiles();
NXBeep();
}
updateView();
} else
NXBeep();
} else
NXBeep();
}
void GameCoordinator::doubleClick( const NXPoint* aPoint ) {
int theTile = tileForClick( aPoint );
if( theTile != -1 ) {
if( tile_array[ theTile ].isSelectable()) {
// if there isn't two tiles selected then
// try to select the tile double clicked.
if(( first_selected_tile == -1 ) || ( second_selected_tile == -1 ))
click( aPoint );
// There must be two tiles
// selected.
if(( first_selected_tile != -1 ) && ( second_selected_tile != -1 )) {
// Remove the tiles from the
// board and update the selectability
// of the surrounding tiles.
assert( tile_array[ first_selected_tile ].tileType() == tile_array[ second_selected_tile ].tileType());
removeTile( first_selected_tile );
removeTile( second_selected_tile );
tile_count_manager->subtractTwo();
unselectTiles();
} else
NXBeep();
} else
NXBeep();
} else
NXBeep();
}
int GameCoordinator::tileForClick( const NXPoint* aPoint ) {
TileIterator index = ( NUMBER_OF_TILES - 1 );
int theTile = -1;
do {
if( !tile_array[ index.value() ].isRemoved()) {
NXRect r = { 0, 0,
TILE_SIZE - TILE_SHIFT, TILE_SIZE - TILE_SHIFT };
r.origin = description_array[ index.value() ]->tileLocation();
if( NXPointInRect( aPoint, &r ))
theTile = index.value();
}
} while(( theTile == -1 ) && ( --index >= 0 ));
return theTile;
}
void GameCoordinator::removeTile( int tile ) {
undoList += tile;
tile_array[ tile ].setRemoved( YES );
tile_array[ tile ].setSelected( NO );
tile_array[ tile ].setSelectable( NO );
updateSelectablilty();
}